<template>
  <div class="app-container">
    <div class="w-table">
      <div class="w-table-left">
        <div class="source-key">
          <div style="width: 60px">角色：</div>

          <el-select
            v-model="sourceKey"
            placeholder="角色"
            style="width: 120px"
            @change="load"
          >
            <el-option
              v-for="item in ['仪玄', '仪玄(小号)']"
              :key="item"
              :value="item"
            />
          </el-select>
        </div>

        <div class="w-table-title">当前装备</div>
        <!-- 当前装备 -->
        <equip-module :config="config" :list="source.equip" />

        <el-divider />

        <top5-module :config="config" :list="top5" />

        <div class="w-table-title">
          <div>仓库</div>
          <!-- 排序 -->
          <el-button type="primary" @click="quickSort">排序</el-button>

          <!-- 删除所有 -->
          <el-button type="danger" @click="removeAll">删除所有</el-button>

          <!-- 最优解 -->
          <el-button type="primary" @click="findBest">最优解</el-button>

          <!-- 导出 -->
          <el-button type="primary" @click="exportExcel">导出</el-button>

          <!-- 导入 -->
          <el-button type="primary" @click="importExcel">导入</el-button>
        </div>
        <!-- 仓库 -->
        <body-module :list="source.db" @edit="onEdit" />
      </div>

      <div>
        <!-- 添加/编辑 装备 -->
        <edit-module
          v-model="form"
          :config="config"
          @add="add"
          @edit="edit"
          @plusEquip="plusEquip"
          @remove="remove"
        />
      </div>
    </div>
  </div>
</template>

<script>
  import { extend } from '@/utils/tool.js'

  import editModule from './edit.vue'
  import bodyModule from './body.vue'
  import equipModule from './equip.vue'
  import top5Module from './top5.vue'

  export default {
    components: {
      editModule,
      bodyModule,
      equipModule,
      top5Module,
    },

    data() {
      return {
        config: {
          equipSuitList: ['云岿如我', '折枝剑歌', '啄木鸟电音'],

          // 属性系数
          coeff: {
            暴击率: 1.57,
            暴击伤害: 1.57,
            生命值: 0.85,
            攻击力: 0.49,
            小攻击: 0.19,
            小生命: 0.38,
            以太伤害: 1.3,
          },

          propertiesList: [
            '暴击率',
            '暴击伤害',
            '生命值',
            '攻击力',
            '小生命',
            '小攻击',
            '以太伤害',
          ],
        },

        form: {
          type: '云岿如我',
          slot: 1,
          暴击率: null,
          暴击伤害: null,
          生命值: null,
          攻击力: null,
          小攻击: null,
          小生命: null,
        },

        top5: [],

        sourceKey: '仪玄',

        source: {
          avatar: {
            name: '仪玄',
          },

          db: [[], [], [], [], [], [], []],

          equip: [{}, {}, {}, {}, {}, {}],
        },
      }
    },

    // 监控source的数据更改,更改时写入浏览器缓存
    watch: {
      source: {
        deep: true,
        handler() {
          localStorage.setItem(this.sourceKey, JSON.stringify(this.source))
        },
      },
    },

    mounted() {
      this.load()
    },

    methods: {
      load() {
        let source = localStorage.getItem(this.sourceKey)
        source = JSON.parse(source)
        if (source) {
          this.source = source
        } else {
          this.source = {
            avatar: {
              name: '仪玄',
            },

            db: [[], [], [], [], [], [], []],

            equip: [],
          }
        }
      },

      equipSave() {},
      save() {},

      add() {
        let item = extend(this.form)
        item.selected = false
        let idx = item.slot
        this.source.db[idx].push(item)
      },

      onEdit(item) {
        this.form = extend(item)
      },

      edit(item) {
        // 遍历2维数组,删除id相等的数据
        for (let i = 0; i < this.source.db.length; i++) {
          for (let j = 0; j < this.source.db[i].length; j++) {
            if (this.source.db[i][j].id === item.id) {
              this.source.db[i][j] = item
              return
            }
          }
        }
      },

      remove(id) {
        // 遍历2维数组,删除id相等的数据
        for (let i = 0; i < this.source.db.length; i++) {
          for (let j = 0; j < this.source.db[i].length; j++) {
            if (this.source.db[i][j].id === id) {
              this.source.db[i].splice(j, 1)
              return
            }
          }
        }
      },

      removeAll() {
        this.source.db = [[], [], [], [], [], [], []]
      },

      calculate() {},

      // 对 source.db 子数组进行排序.
      quickSort() {
        // let id = 17141
        // this.source.db.forEach((arr) => {
        //   arr.forEach((item) => {
        //     item.id = id
        //     id++
        //   })
        // })

        this.source.db.forEach((arr) => {
          // 按子元素的"总分" 从大到小
          arr.sort((a, b) => {
            return b['总分'] - a['总分']
          })
        })
      },

      plusEquip(equip) {
        this.source.equip[equip.slot - 1] = equip
      },

      findBest() {
        // 对 装备库 中所有装备进行排列组合.选中总分最高的
        // 装备库 this.source.db 二维数组,索引1到6的数组,每一数组取一个装备形成'当前装备'
        // 计算 '当前装备' 的总分,然后与 '当前装备' 的总分进行比较,取分数最高的前5个组合

        // 过滤掉空槽位
        const validSlots = this.source.db
          .slice(1, 7)
          .filter((arr) => arr.length > 0)

        // 递归生成笛卡尔积
        const generateCombinations = (arrays) => {
          const result = []
          const helper = (index, current) => {
            if (index === arrays.length) {
              result.push(current)
              return
            }
            arrays[index].forEach((item) => {
              const newItem = { ...item }
              helper(index + 1, [...current, newItem])
            })
          }
          helper(0, [])
          return result
        }

        const combinations = generateCombinations(validSlots)

        // 计算每个组合的总分
        const scoredCombinations = combinations.map((combo) => {
          let totalScore = 0
          combo.forEach((item) => {
            totalScore += item['总分'] || 0
          })
          return { combo, totalScore }
        })

        // 增加规则: 1.组合中必需有且只有二个'折枝剑歌'
        //          2.组合总的暴击率不能超过16个
        // 过滤符合条件的组合
        const filteredCombinations = scoredCombinations.filter(({ combo }) => {
          const countMax1 = combo.filter(
            (item) => item.type === '折枝剑歌',
          ).length

          const countMax2 = combo.filter(
            (item) => item.type === '啄木鸟电音',
          ).length

          const countMax3 = combo.filter(
            (item) => item.type === '云岿如我',
          ).length

          const totalCritRate = combo.reduce(
            (sum, item) => sum + (item.暴击率 || 0),
            0,
          )

          // 必需 有 4个 云岿如我
          if (countMax3 !== 4) {
            return false
          }

          // 必需 有 2个 折枝剑歌 或 2个 啄木鸟电音
          if (countMax1 !== 2 && countMax2 !== 2) {
            return false
          }

          // 大号 2命,暴击率不能超过16个
          if ('仪玄' == this.sourceKey) {
            if (totalCritRate > 16) {
              return false
            }
          }

          // 小号 0命,暴击率不能超过20个
          if ('仪玄(小号)' == this.sourceKey) {
            if (totalCritRate > 20) {
              return false
            }
          }

          return true
        })

        // 排序取前5

        const top5 = filteredCombinations
          .sort((a, b) => b.totalScore - a.totalScore)
          .slice(0, 5)

        this.top5 = top5
        console.log('最优解 Top 5 组合:', top5)
      },

      exportExcel() {
        // 将当前的数据导出为.json文件
        const data = JSON.stringify(this.source)
        const blob = new Blob([data], { type: 'application/json' })
        const url = URL.createObjectURL(blob)
        const a = document.createElement('a')
        a.href = url
        a.download = `${this.sourceKey}.json`
        a.click()
        URL.revokeObjectURL(url)
        console.log('数据已导出为data.json文件')
      },

      importExcel() {
        // 创建文件输入框
        const input = document.createElement('input')
        input.type = 'file'
        input.accept = '.json'
        input.onchange = (event) => {
          const file = event.target.files[0]
          if (!file) return

          const reader = new FileReader()
          reader.onload = (e) => {
            try {
              const data = JSON.parse(e.target.result)
              this.source = data
              localStorage.setItem(this.sourceKey, JSON.stringify(this.source))
              console.log('数据已成功导入')
            } catch (error) {
              console.error('导入失败:', error)
            }
          }
          reader.readAsText(file)
        }
        input.click()
      },
    },
  }
</script>

<style lang="scss" scoped>
  .app-container {
    background-color: #ece9e9;
    height: calc(100vh - 84px);
  }
  .w-table {
    display: grid;
    grid-template-columns: 1fr min-content;
    gap: 20px;
  }
  .w-table-left {
    height: calc(100vh - 120px);
    overflow: auto;
  }

  .w-table-title {
    display: flex;
    justify-content: flex-start;
    align-items: center;
    gap: 20px;
    height: 30px;
    font-size: 22px;
    // font-weight: bold;
  }

  .source-key {
    padding-bottom: 5px;
    margin-bottom: 5px;
    border-bottom: 2px solid #2e66e0;
    display: flex;
    justify-content: flex-start;
    align-items: center;
  }
</style>